

#include "gd32w51x.h"

#include <stdint.h>
#include "i7816_define.h"
#include "i7816_utils.h"

#include "FreeRTOS.h"
#include "timers.h"

#define ETU_TIMER			TIMER2
#define ETU_TIMER_IRQn		TIMER2_IRQn
#define ETU_TIMER_CLK_ENABLE()  rcu_periph_clock_enable(RCU_TIMER2)
#define ETU_TIMER_CLK_FREQ()	(rcu_clock_freq_get(CK_APB1)*2)

#define ETU_TIMER_CLEAR_COUNTOR()	timer_counter_value_config(ETU_TIMER, 0)
#define ETU_TIMER_SET_COUNTOR_PEAK(cnt) 	do{TIMER_CAR(ETU_TIMER) = (uint32_t)cnt;}while(0)
#define ETU_TIMER_GET_COUNTOR_PEAK() 		TIMER_CAR(ETU_TIMER)

volatile uint32_t etuClkCount;
volatile uint8_t etuClkUpdateFlag = 0;

#if 1
void TIMER2_IRQHandler(void)
{
   timer_interrupt_flag_clear(ETU_TIMER, TIMER_INT_FLAG_UP);

   etuClkCount += 65536;
   etuClkUpdateFlag = 1;
}
#endif 

/*======================================时间===============================================*/

void i7816_hal_timer_init(uint32_t freq){

	etuClkCount = 0;

	timer_parameter_struct timer_initpara;
	ETU_TIMER_CLK_ENABLE();
	timer_deinit(ETU_TIMER);
	uint32_t clk = ETU_TIMER_CLK_FREQ();
	
	/* TIMER1 configuration */
	timer_initpara.prescaler         = clk / freq - 1;
	timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
	timer_initpara.counterdirection  = TIMER_COUNTER_UP;
	timer_initpara.period            = 0xFFFF;
	timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
	timer_init(ETU_TIMER, &timer_initpara);
	
	timer_interrupt_flag_clear(ETU_TIMER, TIMER_INT_FLAG_UP);
	timer_interrupt_enable(ETU_TIMER, TIMER_INT_UP);
	nvic_irq_enable(ETU_TIMER_IRQn, 0, 0);

	timer_enable(ETU_TIMER);
}

uint32_t i7816_hal_get_clk_count(void){
	uint32_t count1;
	uint32_t count2;
	uint32_t hwCount;

	do{
		count1 = etuClkCount;
		hwCount = timer_counter_read(ETU_TIMER);
		count2 = etuClkCount;
	}while(count1 != count2);
	
	return (uint32_t)count1 + hwCount;
}

void i7816_hal_delay(uint32_t clk){
	uint32_t c1 = i7816_hal_get_clk_count();
	uint32_t c2;
	do{
		c2 = i7816_hal_get_clk_count();
	}while((c2 - c1) < clk);
}


void i7816_hal_delay_etu(uint32_t etu, uint8_t FiDi){
	i7816_hal_delay(i7816_etu2clk(etu, FiDi));
}

void i7816_hal_delay_ms(uint32_t ms){
	vTaskDelay(pdMS_TO_TICKS(ms));
}

